package com.fingard.dsp.bank.directbank.allinpay02;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.Date;
import java.util.HashMap;

/**
 * AllInPay02-通联批量代收付
 */
public class AllInPay02BatPayRec extends AllInPay02Base implements IBatPayRec {
    public boolean isFromSinglePay = false;//是否是单笔转批量

    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        if ("1988JFB".equals(p_req1988.reqHeader.commandCode)) {
            return d_JFBBatPayRec(p_req1988);
        } else {
            return d_BatPayRec(p_req1988);
        }
    }

    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        if ("9188Agrm".equals(p_req9188.reqHeader.commandCode)) {
            return dealBatAgrmPay(p_req9188);
        } else if ("9188JFB".equals(p_req9188.reqHeader.commandCode)) {
            return d_JFBBatPayRec(p_req9188);
        } else {
            return d_BatPayRec(p_req9188);
        }
    }

    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        if ("1988JFB".equals(p_req1998.reqHeader.commandCode)) {
            return d_QryJFBBatPayRec(p_req1998);
        } else {
            return d_QryBatPayRec(p_req1998);
        }
    }

    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        if ("9188JFB".equals(p_req9198.reqHeader.commandCode)) {
            return d_QryJFBBatPayRec(p_req9198);
        } else {
            return d_QryBatPayRec(p_req9198);
        }
    }

    public RetAtsBatPayRec dealBatAgrmPay(ReqBatPayRec p_reqBat) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        retAts.reqSeqID = p_reqBat.reqBatchNO;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqBat.ownAct, "bat");
            if (actItem == null) {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号" + p_reqBat.ownAct + "的批量商户配置节点";
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
                retAts.writeRetToATS();
                return retAts;
            }

            AllInPay02Header bankHeader = new AllInPay02Header();
            bankHeader.TRX_CODE = "310016";
            bankHeader.REQ_SN = p_reqBat.reqBatchNO;

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeAgrmCommonHeader(xmlWriter, bankHeader, actItem);
            xmlWriter.writeStartElement("BODY");
            xmlWriter.writeStartElement("TRANS_SUM");

            int tmpRdCount = 0;
            while (p_reqBat.readRecord()) {
                if (tmpRdCount == 0) {
                    String BUSINESS_CODE = this.getBankConfig().getMapValueBySrcXE("BUSINESS_CODE_9188", "srcCode", "desCode", p_reqBat.readedDetail.srcXElement, p_reqBat.useType);
                    xmlWriter.writeElementString("BUSINESS_CODE", BUSINESS_CODE);
                    xmlWriter.writeElementString("MERCHANT_ID", actItem.merchantId);
                    xmlWriter.writeElementString("SUBMIT_TIME", Format.DateTime14Format.format(p_reqBat.getPayDateTime()));
                    xmlWriter.writeElementString("TOTAL_ITEM", p_reqBat.totalNum);
                    xmlWriter.writeElementString("TOTAL_SUM", StringHelper.amountMultiply100(p_reqBat.totalAmt));
                    xmlWriter.writeEndElement();

                    xmlWriter.writeStartElement("TRANS_DETAILS");
                }
                tmpRdCount++;
                XElement tmpXElement = new XElement("FASTTRX_DETAIL", "");
                tmpXElement.addChild(new XElement("SN", String.format("%04d", tmpRdCount)));
                tmpXElement.addChild(new XElement("AGRMNO", p_reqBat.readedDetail.authCode));
                tmpXElement.addChild(new XElement("ACCOUNT_NO", p_reqBat.readedDetail.payAct));
                tmpXElement.addChild(new XElement("ACCOUNT_NAME", p_reqBat.readedDetail.payName));
                tmpXElement.addChild(new XElement("CURRENCY", convertCurToBank(p_reqBat.readedDetail.payCur)));
                String ID_TYPE = "";
                String ID = "";
                String ifNeed = getBankConfig().getMapValueByKey("needCertBank", p_reqBat.readedDetail.payBankCode);
                if (ifNeed.toLowerCase().equals("true")) {
                    String tmpMapped_ID_TYPE = this.convertCertTypeToBank(p_reqBat.readedDetail.certType);
                    if (StringHelper.hasAnyChar(tmpMapped_ID_TYPE) && StringHelper.hasAnyChar(p_reqBat.readedDetail.certNum)) {
                        ID_TYPE = tmpMapped_ID_TYPE;
                        ID = p_reqBat.readedDetail.certNum;
                    }
                }
                tmpXElement.addChild(new XElement("ID_TYPE", ID_TYPE));
                tmpXElement.addChild(new XElement("ID", ID));
                tmpXElement.addChild(new XElement("TEL", p_reqBat.readedDetail.cellPhone));
                tmpXElement.addChild(new XElement("CVV2", p_reqBat.readedDetail.cvv2));
                tmpXElement.addChild(new XElement("VAILDDATE", p_reqBat.readedDetail.expiredDate));
                tmpXElement.addChild(new XElement("AMOUNT", StringHelper.amountMultiply100(p_reqBat.readedDetail.payAmount)));
                tmpXElement.addChild(new XElement("E_USER_CODE", ""));
                tmpXElement.addChild(new XElement("CUST_USERID", p_reqBat.readedDetail.askNumber));
                String REMARK = StringHelper.getFirstNotEmpty(p_reqBat.readedDetail.memo, p_reqBat.readedDetail.useType, p_reqBat.readedDetail.description);
                String SUMMARY = StringHelper.getFirstNotEmpty(p_reqBat.readedDetail.purpose, REMARK);
                REMARK = StringHelper.subStringByGBKByte(REMARK, 50);
                SUMMARY = StringHelper.subStringByGBKByte(SUMMARY, 140);
                tmpXElement.addChild(new XElement("SUMMARY", SUMMARY));
                tmpXElement.addChild(new XElement("REMARK", REMARK));
                if ("1".equals(p_reqBat.readedDetail.isPrivate)) {
                    tmpXElement.addChild(new XElement("UNION_BANK", ""));
                } else {
                    tmpXElement.addChild(new XElement("UNION_BANK", p_reqBat.readedDetail.cnapsCode));
                }
                tmpXElement.addChild(new XElement("SETTACCT", ""));
                this.nodeAnalysis(p_reqBat.readedDetail.srcXElement, tmpXElement, this.getCharset("GBK", p_reqBat.reqHeader.transType));
                xmlWriter.writeXElement(tmpXElement);
            }
            xmlWriter.writeEndDocument();
            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), actItem);
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

                if (tmpBkReader != null) {
                    retAts.respCode = "0";
                    retAts.respInfo = tmpBkReader.getFirstText("/AIPG/INFO/ERR_MSG");
                    retAts.transState = tmpBkReader.getFirstText("/AIPG/INFO/RET_CODE");
                    retAts.payInfoCode = tmpBkReader.getFirstText("/AIPG/INFO/RET_CODE");
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.reqSeqID = p_reqBat.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        retAts.reqSeqID = p_reqBat.reqBatchNO;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqBat.ownAct, "bat");
            if (actItem == null) {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号" + p_reqBat.ownAct + "的批量商户配置节点";
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
                retAts.writeRetToATS();
                return retAts;
            }

            String keyTransTypeForMap = p_reqBat.reqHeader.transType;
            if ("1908".equals(keyTransTypeForMap) || "6908".equals(keyTransTypeForMap)) {
                keyTransTypeForMap = "1988";
            }

            AllInPay02Header bankHeader = new AllInPay02Header();
            if (keyTransTypeForMap.equals("1988")) {
                bankHeader.TRX_CODE = "100002";
            } else if (p_reqBat.reqHeader.transType.equals("9188")) {
                bankHeader.TRX_CODE = "100001";
            }
            bankHeader.REQ_SN = p_reqBat.reqBatchNO;

            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            writeCommonHeader(xmlWriter, bankHeader, actItem);
            xmlWriter.writeStartElement("BODY");
            xmlWriter.writeStartElement("TRANS_SUM");
            int tmpRdCount = 0;
            while (p_reqBat.readRecord()) {
                if (tmpRdCount == 0) {
                    String BUSINESS_CODE = this.getBankConfig().getMapValueBySrcXE("BUSINESS_CODE_" + keyTransTypeForMap, "srcCode", "desCode", p_reqBat.readedDetail.srcXElement, p_reqBat.useType);
                    xmlWriter.writeElementString("BUSINESS_CODE", BUSINESS_CODE);
                    xmlWriter.writeElementString("MERCHANT_ID", actItem.merchantId);
                    xmlWriter.writeElementString("SUBMIT_TIME", Format.DateTime14Format.format(p_reqBat.getPayDateTime()));
                    xmlWriter.writeElementString("TOTAL_ITEM", p_reqBat.totalNum);
                    xmlWriter.writeElementString("TOTAL_SUM", StringHelper.amountMultiply100(p_reqBat.totalAmt));
                    xmlWriter.writeEndElement();

                    xmlWriter.writeStartElement("TRANS_DETAILS");
                }
                tmpRdCount++;
                XElement tmpXElement = new XElement("TRANS_DETAIL", "");
                tmpXElement.addChild(new XElement("SN", String.format("%04d", tmpRdCount)));

                String[] findValues = new String[2];
                if ("1988".equals(keyTransTypeForMap)) {
                    findValues[0] = p_reqBat.readedDetail.recBankCode;
                    findValues[1] = p_reqBat.readedDetail.recAreaName;
                } else if ("9188".equals(keyTransTypeForMap)) {
                    findValues[0] = p_reqBat.readedDetail.payBankCode;
                    findValues[1] = p_reqBat.readedDetail.payAreaName;
                }
                HashMap<String, String> BANK_CODE = this.getBankConfig().getMapAdvanceValues("BankCodeMapping", new String[]{"ATSBankCode", "ATSAreaName"}, new String[]{"value", "newAreaName"}, findValues);
                if (BANK_CODE != null && BANK_CODE.size() > 0 && BANK_CODE.containsKey("value")) {
                    tmpXElement.addChild(new XElement("BANK_CODE", BANK_CODE.get("value")));
                } else {
                    tmpXElement.addChild(new XElement("BANK_CODE", findValues[0]));
                }

                if (BANK_CODE != null && BANK_CODE.size() > 0 && BANK_CODE.containsKey("newAreaName")) {
                    if (StringHelper.hasAnyChar(BANK_CODE.get("newAreaName"))) {
                        if ("1988".equals(keyTransTypeForMap)) {
                            p_reqBat.readedDetail.recAreaName = BANK_CODE.get("newAreaName");
                            p_reqBat.readedDetail.recStandardArea = "";
                        } else if ("9188".equals(keyTransTypeForMap)) {
                            p_reqBat.readedDetail.payAreaName = BANK_CODE.get("newAreaName");
                            p_reqBat.readedDetail.payStandardArea = "";
                        }
                    }
                }

                if (p_reqBat.readedDetail.cardType.equals("1")) {
                    tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "01"));
                } else if (p_reqBat.readedDetail.cardType.equals("3")) {
                    tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "02"));
                } else {
                    tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "00"));
                }
                if (keyTransTypeForMap.equals("1988")) {
                    tmpXElement.addChild(new XElement("ACCOUNT_NO", p_reqBat.readedDetail.recAct));
                    tmpXElement.addChild(new XElement("ACCOUNT_NAME", p_reqBat.readedDetail.recName));
                } else if (keyTransTypeForMap.equals("9188")) {
                    tmpXElement.addChild(new XElement("ACCOUNT_NO", p_reqBat.readedDetail.payAct));
                    tmpXElement.addChild(new XElement("ACCOUNT_NAME", p_reqBat.readedDetail.payName));
                }
                String[] tmpPC = p_reqBat.readedDetail.getOppProvinceAndCity();
                tmpXElement.addChild(new XElement("PROVINCE", tmpPC[0]));
                //该逻辑不能起作用，需注释，否则通联无法获取省市信息
//                if(tmpPC[1].equals(tmpPC[0])){  
//                	tmpPC[1] = "";
//                }
                tmpXElement.addChild(new XElement("CITY", tmpPC[1]));
                tmpXElement.addChild(new XElement("BANK_NAME", p_reqBat.readedDetail.getOppBankLocation()));
                if (p_reqBat.readedDetail.isPrivate.equals("1")) {
                    tmpXElement.addChild(new XElement("ACCOUNT_PROP", "0"));
                } else {
                    tmpXElement.addChild(new XElement("ACCOUNT_PROP", "1"));
                }
                tmpXElement.addChild(new XElement("AMOUNT", StringHelper.amountMultiply100(p_reqBat.readedDetail.payAmount)));
                tmpXElement.addChild(new XElement("CURRENCY", convertCurToBank(p_reqBat.readedDetail.payCur)));
                String ID_TYPE = "";
                String ID = "";
                if (keyTransTypeForMap.equals("9188")) {
                    String ifNeed = getBankConfig().getMapValueByKey("needCertBank", p_reqBat.readedDetail.payBankCode);
                    if (ifNeed.toLowerCase().equals("true")) {
                        String tmpMapped_ID_TYPE = this.convertCertTypeToBank(p_reqBat.readedDetail.certType);
                        if (StringHelper.hasAnyChar(tmpMapped_ID_TYPE) && StringHelper.hasAnyChar(p_reqBat.readedDetail.certNum)) {
                            ID_TYPE = tmpMapped_ID_TYPE;
                            ID = p_reqBat.readedDetail.certNum;
                        }
                    }
                }
                tmpXElement.addChild(new XElement("ID_TYPE", ID_TYPE));
                tmpXElement.addChild(new XElement("ID", ID));
                tmpXElement.addChild(new XElement("CUST_USERID", p_reqBat.readedDetail.askNumber));
                String REMARK = StringHelper.getFirstNotEmpty(p_reqBat.readedDetail.memo, p_reqBat.readedDetail.useType, p_reqBat.readedDetail.description);
                String SUMMARY = StringHelper.getFirstNotEmpty(p_reqBat.readedDetail.purpose, REMARK);
                REMARK = StringHelper.subStringByGBKByte(REMARK, 50);
                SUMMARY = StringHelper.subStringByGBKByte(SUMMARY, 140);
                tmpXElement.addChild(new XElement("REMARK", REMARK));
                tmpXElement.addChild(new XElement("SUMMARY", SUMMARY));
                if ("1".equals(p_reqBat.readedDetail.isPrivate)) {
                    tmpXElement.addChild(new XElement("UNION_BANK", ""));
                } else {
                    tmpXElement.addChild(new XElement("UNION_BANK", p_reqBat.readedDetail.cnapsCode));
                }

                this.nodeAnalysis(p_reqBat.readedDetail.srcXElement, tmpXElement, this.getCharset("GBK", p_reqBat.reqHeader.transType));

                xmlWriter.writeXElement(tmpXElement);
            }
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), actItem);

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    retAts.respCode = "0";
                    retAts.respInfo = tmpBkReader.getFirstText("/AIPG/INFO/ERR_MSG");
                    retAts.reqSeqID = tmpBkReader.getFirstText("/AIPG/INFO/REQ_SN");
                    retAts.transState = tmpBkReader.getFirstText("/AIPG/INFO/RET_CODE");
                    retAts.payInfoCode = tmpBkReader.getFirstText("/AIPG/INFO/RET_CODE");
                    if (isFromSinglePay) {//单笔转批量
                        retAts.transState = "H+" + retAts.transState;
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.reqSeqID = p_reqBat.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.toString();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    /**
     * 接口文档：https://jfb.allinpay.com/jfbgw/doc/toDoc.dsr#31
     *
     * @param p_reqBat
     * @return
     * @throws Exception
     */
    public RetAtsBatPayRec d_JFBBatPayRec(ReqBatPayRec p_reqBat) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        retAts.reqSeqID = p_reqBat.reqBatchNO;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqBat.ownAct, "bat");
            if (actItem == null) {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号" + p_reqBat.ownAct + "的批量商户配置节点";
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
                retAts.writeRetToATS();
                return retAts;
            }

            String keyTransTypeForMap = p_reqBat.reqHeader.transType;

            AllInPay02Header bankHeader = new AllInPay02Header();
            if ("1988".equals(keyTransTypeForMap)) {
                bankHeader.TRX_CODE = "100002";
            } else {
                bankHeader.TRX_CODE = "100001";
            }
            bankHeader.REQ_SN = p_reqBat.reqBatchNO;

            XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
            writeJFBCommonHeader(xmlWriter, bankHeader, actItem);
            xmlWriter.writeStartElement("BODY");
            xmlWriter.writeStartElement("TRANS_SUM");
            int tmpRdCount = 0;
            while (p_reqBat.readRecord()) {
                if (tmpRdCount == 0) {
                    String BUSINESS_CODE = this.getBankConfig().getMapValueBySrcXE("BUSINESS_CODE_" + keyTransTypeForMap, "srcCode", "desCode", p_reqBat.readedDetail.srcXElement, p_reqBat.useType);
                    xmlWriter.writeElementString("BUSINESS_CODE", BUSINESS_CODE);
                    xmlWriter.writeElementString("TOTAL_ITEM", p_reqBat.totalNum);
                    xmlWriter.writeElementString("TOTAL_SUM", StringHelper.amountMultiply100(p_reqBat.totalAmt));
                    xmlWriter.writeEndElement();

                    xmlWriter.writeStartElement("TRANS_DETAILS");
                }
                tmpRdCount++;
                XElement tmpXElement = new XElement("TRANS_DETAIL", "");
                tmpXElement.addChild(new XElement("SN", String.format("%04d", tmpRdCount)));
                if (p_reqBat.readedDetail.cardType.equals("1")) {
                    tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "01"));
                } else if (p_reqBat.readedDetail.cardType.equals("3")) {
                    tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "02"));
                } else {
                    tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "00"));
                }
                if (p_reqBat.readedDetail.isPrivate.equals("1")) {
                    tmpXElement.addChild(new XElement("ACCOUNT_PROP", "0"));
                } else {
                    tmpXElement.addChild(new XElement("ACCOUNT_PROP", "1"));
                }
                if ("1988".equals(keyTransTypeForMap)) {
                    tmpXElement.addChild(new XElement("ACCOUNT_NO", p_reqBat.readedDetail.recAct));
                    tmpXElement.addChild(new XElement("ACCOUNT_NAME", p_reqBat.readedDetail.recName));
                    tmpXElement.addChild(new XElement("BANK_CODE", getBankConfig().getMapValueByKey("contractBankMapping", p_reqBat.readedDetail.recBankCode)));
                } else if ("9188".equals(keyTransTypeForMap)) {
                    tmpXElement.addChild(new XElement("ACCOUNT_NO", p_reqBat.readedDetail.payAct));
                    tmpXElement.addChild(new XElement("ACCOUNT_NAME", p_reqBat.readedDetail.payName));
                    tmpXElement.addChild(new XElement("BANK_CODE", getBankConfig().getMapValueByKey("contractBankMapping", p_reqBat.readedDetail.payBankCode)));
                }

                if ("1".equals(p_reqBat.readedDetail.isPrivate)) {
                    tmpXElement.addChild(new XElement("UNION_BANK", ""));
                } else {
                    tmpXElement.addChild(new XElement("UNION_BANK", p_reqBat.readedDetail.cnapsCode));
                }
                tmpXElement.addChild(new XElement("BANK_NAME", p_reqBat.readedDetail.getOppBankLocation()));
                tmpXElement.addChild(new XElement("E_USER_CODE", ""));
                String ID_TYPE = "";
                String ID = "";
                if (keyTransTypeForMap.equals("9188")) {
                    String ifNeed = getBankConfig().getMapValueByKey("needCertBank", p_reqBat.readedDetail.payBankCode);
                    if (ifNeed.toLowerCase().equals("true")) {
                        String tmpMapped_ID_TYPE = this.convertCertTypeToBank(p_reqBat.readedDetail.certType);
                        if (StringHelper.hasAnyChar(tmpMapped_ID_TYPE) && StringHelper.hasAnyChar(p_reqBat.readedDetail.certNum)) {
                            ID_TYPE = tmpMapped_ID_TYPE;
                            ID = p_reqBat.readedDetail.certNum;
                        }
                    }
                }
                tmpXElement.addChild(new XElement("ID_TYPE", ID_TYPE));
                tmpXElement.addChild(new XElement("ID", ID));
                tmpXElement.addChild(new XElement("TEL", p_reqBat.readedDetail.cellPhone));
                tmpXElement.addChild(new XElement("AMOUNT", StringHelper.amountMultiply100(p_reqBat.readedDetail.payAmount)));
                tmpXElement.addChild(new XElement("CURRENCY", convertCurToBank(p_reqBat.readedDetail.payCur)));
                String[] tmpPC = p_reqBat.readedDetail.getOppProvinceAndCity();
                tmpXElement.addChild(new XElement("PROVINCE", tmpPC[0]));
                //该逻辑不能起作用，需注释，否则通联无法获取省市信息
//                if(tmpPC[1].equals(tmpPC[0])){
//                	tmpPC[1] = "";
//                }
                tmpXElement.addChild(new XElement("CITY", tmpPC[1]));
                tmpXElement.addChild(new XElement("CUST_USERID", p_reqBat.readedDetail.askNumber));
                String REMARK = StringHelper.getFirstNotEmpty(p_reqBat.readedDetail.memo, p_reqBat.readedDetail.useType, p_reqBat.readedDetail.description);
                String SUMMARY = StringHelper.getFirstNotEmpty(p_reqBat.readedDetail.purpose, REMARK);
                REMARK = StringHelper.subStringByGBKByte(REMARK, 50);
                SUMMARY = StringHelper.subStringByGBKByte(SUMMARY, 140);
                tmpXElement.addChild(new XElement("REMARK", REMARK));
                tmpXElement.addChild(new XElement("SUMMARY", SUMMARY));

                this.nodeAnalysis(p_reqBat.readedDetail.srcXElement, tmpXElement, this.getCharset("GBK", p_reqBat.reqHeader.transType));

                xmlWriter.writeXElement(tmpXElement);
            }
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendJFBToBank(xmlWriter.toXmlString(), actItem, bankHeader.REQ_SN);

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    retAts.respCode = "0";
                    retAts.respInfo = tmpBkReader.getFirstText("/AIPG/HEAD/RET_MSG");
                    retAts.reqSeqID = tmpBkReader.getFirstText("/AIPG/HEAD/REQ_SN");
                    retAts.transState = "JH+" + tmpBkReader.getFirstText("/AIPG/HEAD/RET_CODE");
                    retAts.payInfoCode = tmpBkReader.getFirstText("/AIPG/HEAD/RET_CODE");
//                    if (isFromSinglePay) {//单笔转批量
//                        retAts.transState = "H+" + retAts.transState;
//                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.reqSeqID = p_reqBat.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.toString();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);
        retAts.reqSeqID = p_reqQryBat.reqBatchNO;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQryBat.ownAct, "bat");
            if (actItem != null) {
                AllInPay02Header bankHeader = new AllInPay02Header();
                bankHeader.REQ_SN = p_reqQryBat.reqHeader.transSeqID;
                bankHeader.TRX_CODE = "200004";

                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                writeCommonHeader(xmlWriter, bankHeader, actItem);//写入通用的头部节点
                xmlWriter.writeStartElement("QTRANSREQ");
                xmlWriter.writeElementString("MERCHANT_ID", actItem.merchantId);
                xmlWriter.writeElementString("QUERY_SN", p_reqQryBat.reqBatchNO);
                xmlWriter.writeElementString("STATUS", "2");
                xmlWriter.writeElementString("TYPE", "1");
                xmlWriter.writeElementClosed("START_DAY");
                xmlWriter.writeElementClosed("END_DAY");
                xmlWriter.writeEndDocument();

                String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), actItem);

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String RET_CODE = tmpBkReader.getFirstText("/AIPG/INFO/RET_CODE");
                        String ERR_MSG = tmpBkReader.getFirstText("/AIPG/INFO/ERR_MSG");
                        if (RET_CODE.equals("1002")) {
						/*批量交易结果的查询
						建议至少间隔5分钟查询一次
						对于50分钟内通联一直返回1002的，应确认该笔交易失败，通联没有成功接收，应立刻停止继续查询。*/
                            if (tmpStrRet[1].indexOf("QTDETAIL") >= 0) {
                                retAts.respCode = "-1";
                                retAts.respInfo = "RET_CODE为1002但QTDETAIL节点非空";
                            } else {
                                double minsPasted = DateHelper.getDifferMins(new Date(), p_reqQryBat.getBgnDateTime());
                                double needMins = 55;
                                int notExistWaitMins = this.getBankConfig().getValueAsInt("notExistWaitMins");
                                if (notExistWaitMins > 0) {
                                    needMins = Float.valueOf(String.valueOf(notExistWaitMins));
                                }
                                double waitMins = needMins - minsPasted;
                                if (waitMins > 0) {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "请于" + String.format("%1$.2f", waitMins) + "分钟后再次查询（通联对“无此交易”的情况有50分钟的要求）";
                                } else {
                                    retAts.respCode = "0";
                                    retAts.reqSeqID = p_reqQryBat.reqBatchNO;
                                    retAts.transState = RET_CODE;
                                    retAts.payInfoCode = RET_CODE;
                                    retAts.respInfo = ERR_MSG;
                                    retAts.writeBeforeDetail();
                                }
                            }
                        } else if (RET_CODE.equals("1000") || RET_CODE.equals("1001")) {
                            retAts.respCode = "-1";
                            retAts.respInfo = ERR_MSG;
                        } else {
                            retAts.respCode = "0";
                            retAts.respInfo = ERR_MSG;
                            retAts.reqSeqID = p_reqQryBat.reqBatchNO;
                            retAts.transState = RET_CODE;
                            retAts.payInfoCode = RET_CODE;
                            retAts.writeBeforeDetail();

                            while (tmpBkReader.read("/AIPG/QTRANSRSP/QTDETAIL")) {
                                RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                if (p_reqQryBat.reqHeader.transType.equals("1998")) {
                                    tmpRetDetail.recAct = tmpBkReader.readedXElement.getSingleText("ACCOUNT_NO");
                                    tmpRetDetail.recName = tmpBkReader.readedXElement.getSingleText("ACCOUNT_NAME");
                                } else if (p_reqQryBat.reqHeader.transType.equals("9198")) {
                                    tmpRetDetail.payAct = tmpBkReader.readedXElement.getSingleText("ACCOUNT_NO");
                                    tmpRetDetail.payName = tmpBkReader.readedXElement.getSingleText("ACCOUNT_NAME");
                                }
                                tmpRetDetail.payAmount = StringHelper.amountDivide100(tmpBkReader.readedXElement.getSingleText("AMOUNT"));
                                tmpRetDetail.postScript = tmpBkReader.readedXElement.getSingleText("CUST_USERID");
                                String DETAIL_RET_CODE = tmpBkReader.readedXElement.getSingleText("RET_CODE");
                                tmpRetDetail.result = DETAIL_RET_CODE;
                                tmpRetDetail.memo = tmpBkReader.readedXElement.getSingleText("ERR_MSG");
                                tmpRetDetail.payInfoCode = DETAIL_RET_CODE;
                                if ("3999".equals(DETAIL_RET_CODE)) {
                                    tmpRetDetail.payInfoCode = tmpRetDetail.memo;
                                }
                                retAts.writeRetDetail(tmpRetDetail);
                            }
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqQryBat.ownAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }

    public RetAtsQryBatPayRec d_QryJFBBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);
        retAts.reqSeqID = p_reqQryBat.reqBatchNO;

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_reqQryBat.ownAct, "bat");
            if (actItem != null) {
                AllInPay02Header bankHeader = new AllInPay02Header();
                bankHeader.REQ_SN = p_reqQryBat.reqBatchNO;
                bankHeader.TRX_CODE = "200004";

                XmlTextWriter xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                writeJFBCommonHeader(xmlWriter, bankHeader, actItem);//写入通用的头部节点
                xmlWriter.writeStartElement("BODY");
                xmlWriter.writeStartElement("QTRANSREQ");
                xmlWriter.writeElementString("SRC_BATCHID", p_reqQryBat.reqBatchNO);
                xmlWriter.writeElementString("SRC_SN", "");
                xmlWriter.writeEndDocument();

                String[] tmpStrRet = sendJFBToBank(xmlWriter.toXmlString(), actItem, bankHeader.REQ_SN);

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String RET_CODE = tmpBkReader.getFirstText("/AIPG/HEAD/RET_CODE");
                        String ERR_MSG = tmpBkReader.getFirstText("/AIPG/HEAD/RET_MSG");
                        if (RET_CODE.equals("1002")) {
						/*批量交易结果的查询
						建议至少间隔5分钟查询一次
						对于50分钟内通联一直返回1002的，应确认该笔交易失败，通联没有成功接收，应立刻停止继续查询。*/
                            if (tmpStrRet[1].indexOf("QTDETAIL") >= 0) {
                                retAts.respCode = "-1";
                                retAts.respInfo = "RET_CODE为1002但QTDETAIL节点非空";
                            } else {
                                if (canBeNotExist(p_reqQryBat, retAts, 50)) {
                                    retAts.respCode = "0";
                                    retAts.reqSeqID = p_reqQryBat.reqBatchNO;
                                    retAts.transState = "JH+" + RET_CODE;
                                    retAts.payInfoCode = RET_CODE;
                                    retAts.respInfo = ERR_MSG;
                                }
                            }
                        } else if (RET_CODE.equals("1000")) {
                            retAts.respCode = "-1";
                            retAts.respInfo = ERR_MSG;
                        } else {
                            retAts.respCode = "0";
                            retAts.respInfo = ERR_MSG;
                            retAts.reqSeqID = p_reqQryBat.reqBatchNO;

                            String status = tmpBkReader.getFirstText("/AIPG/BODY/QTSUM/STATUS");
                            if ("1".equals(status)) {
                                while (tmpBkReader.read("/AIPG/BODY/QTDETAILS/QTDETAIL")) {
                                    RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                                    if (p_reqQryBat.reqHeader.transType.equals("1998")) {
                                        tmpRetDetail.recAct = tmpBkReader.readedXElement.getSingleText("ACCOUNT_NO");
                                        tmpRetDetail.recName = tmpBkReader.readedXElement.getSingleText("ACCOUNT_NAME");
                                    } else if (p_reqQryBat.reqHeader.transType.equals("9198")) {
                                        tmpRetDetail.payAct = tmpBkReader.readedXElement.getSingleText("ACCOUNT_NO");
                                        tmpRetDetail.payName = tmpBkReader.readedXElement.getSingleText("ACCOUNT_NAME");
                                    }
                                    tmpRetDetail.payAmount = StringHelper.amountDivide100(tmpBkReader.readedXElement.getSingleText("AMOUNT"));
                                    tmpRetDetail.postScript = tmpBkReader.readedXElement.getSingleText("CUST_USERID");
                                    String resultCode = tmpBkReader.readedXElement.getSingleText("RESULT_CODE");
                                    tmpRetDetail.result = "JH+" + RET_CODE + "+JD+" + resultCode;
                                    tmpRetDetail.memo = tmpBkReader.readedXElement.getSingleText("RESULT_MSG");
                                    tmpRetDetail.payInfoCode = resultCode;
                                    if ("3999".equals(resultCode)) {
                                        tmpRetDetail.payInfoCode = tmpRetDetail.memo;
                                    }
                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            } else {
                                retAts.respCode = "-1";
                                retAts.respInfo = "银行处理中，请稍后查询！";
                            }
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqQryBat.ownAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}